package com.internetCafes.spms.web.extend.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.internetCafes.spms.common.AIRecognize.recognizer.impl.QRCodeRecognizer;
import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.common.base.BaseWebController;
import com.internetCafes.spms.common.module.excel.ExcelUtils;
import com.internetCafes.spms.common.module.excel.po.EntCertiOtherExcel;
import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.core.annotation.SysLog;
import com.internetCafes.spms.core.utils.DateUtils;
import com.internetCafes.spms.core.utils.FileUtils;
import com.internetCafes.spms.core.utils.IdWorker;
import com.internetCafes.spms.core.utils.R;
import com.internetCafes.spms.web.certificate.vo.AIRecognizeInfo;
import com.internetCafes.spms.web.extend.model.EntCertiHonor;
import com.internetCafes.spms.web.extend.model.EntCertiIso;
import com.internetCafes.spms.web.extend.model.EntCertiOther;
import com.internetCafes.spms.web.extend.model.EntCertiQuali;
import com.internetCafes.spms.web.extend.service.*;
import com.internetCafes.spms.web.extend.vo.EntCertiOtherVo;
import com.internetCafes.spms.web.sys.model.ResourceInfo;
import com.internetCafes.spms.web.sys.service.ConfInfoService;
import com.internetCafes.spms.web.sys.service.ResourceInfoService;
import com.sms.common.util.hutool.core.collection.CollectionUtil;
import com.sms.common.util.hutool.core.util.ObjectUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author LinYe
 * @since 2020-12-08
 */
@RestController
@RequestMapping("/cert/entOther")
public class EntCertiOtherController extends BaseWebController {

    @Autowired
    IEntCertiOtherService entCertiOtherService;

    @Autowired
    ResourceInfoService resourceInfoService;

    @Autowired
    QRCodeRecognizer qrCodeRecognizer;

    @Autowired
    IEntCertiHonorService entCertiHonorService;

    @Autowired
    IEntCertiIsoService entCertiIsoService;

    @Autowired
    IEntCertiQualiService entCertiQualiService;

    @Autowired
    IEntCertiQualiConfService entCertiQualiConfService;

    @Autowired
    ConfInfoService confInfoService;

    @Value("${system.upload.pic}")
    private String picPath;

    @SysLog("保存其他证书")
    @PostMapping("/save")
    @RequiresPermissions("certificate:certificateInfo:save")
    public R save(@RequestBody EntCertiOtherVo entCertiOtherVo) {
        entCertiOtherVo.setStatus(CommonConstants.CommonStatus.DISABLE);
        QueryWrapper<EntCertiOther> entCertiOtherWrapper = new QueryWrapper<>();
        entCertiOtherWrapper.eq("code",entCertiOtherVo.getCode());
        int count = entCertiOtherService.count(entCertiOtherWrapper);
        if (count > 0) {
            return R.error("证书已存在");
        }
        entCertiOtherService.save(entCertiOtherVo);
        if (StringUtils.isNotBlank(entCertiOtherVo.getCertiPic())) {
            ResourceInfo r = new ResourceInfo(ShiroUtils.getUserEntity().getId(), CommonConstants.RESOURCE_PIC_ENT_OTHER, entCertiOtherVo.getId(), "pic" + File.separator + entCertiOtherVo.getCertiPic());
            resourceInfoService.save(r);
        }
        return R.ok();
    }

    @SysLog("作废其他证书")
    @PostMapping("/delete/{id}")
    @RequiresPermissions("certificate:certificateInfo:delete")
    public R delete(@PathVariable("id") Long id) {
        EntCertiOther entCertiOther = new EntCertiOther();
        entCertiOther.setId(id);
        entCertiOther.setStatus(CommonConstants.CommonStatus.DELETED);
        if (entCertiOtherService.updateById(entCertiOther)) {
            return R.ok();
        } else {
            return R.error("您要删除的证书不存在");
        }
    }

    @SysLog("更新其他证书")
    @PostMapping("/update")
    @RequiresPermissions("certificate:certificateInfo:update")
    public R update(@RequestBody EntCertiOtherVo entCertiOtherVo) {
        if (entCertiOtherService.updateById(entCertiOtherVo)) {
            Map<String,Object> params = new HashMap<>();
            if (entCertiOtherVo.getCertiPic()!=null) {
                params.put("moduleCode", CommonConstants.RESOURCE_PIC_ENT_OTHER);
                params.put("moduleId", entCertiOtherVo.getId());
                resourceInfoService.deleteByModuleAndUserId(params);
                if (!"".equals(entCertiOtherVo.getCertiPic())) {
                    ResourceInfo r = new ResourceInfo(ShiroUtils.getUserEntity().getId(), CommonConstants.RESOURCE_PIC_ENT_OTHER, entCertiOtherVo.getId(), "pic" + File.separator + entCertiOtherVo.getCertiPic());
                    resourceInfoService.save(r);
                }
            }
            return R.ok();
        } else {
            return R.error("您要更新的证书不存在");
        }
    }

    @GetMapping("/getDetail/{id}")
    @RequiresPermissions("certificate:certificateInfo:info")
    public R get(@PathVariable("id") Long id) {
        EntCertiOther entCertiOther = entCertiOtherService.getById(id);
        if (entCertiOther != null) {
            Map<String,Object>params = new HashMap<>();
            params.put("moduleCode", CommonConstants.RESOURCE_PIC_ENT_OTHER);
            params.put("moduleId", id);
            List<ResourceInfo> resourceInfoList = resourceInfoService.query(params);
            EntCertiOtherVo entCertiOtherVo=new EntCertiOtherVo();
            BeanUtils.copyProperties(entCertiOther,entCertiOtherVo);
            if (CollectionUtil.isNotEmpty(resourceInfoList)) {
                entCertiOtherVo.setCertiPic(resourceInfoList.get(0).getPath());
            }
            return R.ok().put("data", entCertiOtherVo);
        } else {
            return R.error("您要查询的证书不存在");
        }
    }

    @PostMapping("/paging")
    @RequiresPermissions("certificate:certificateInfo:list")
    public R paging(@RequestBody EntCertiOtherVo entCertiOtherVo) {
        if (entCertiOtherVo.getStatus()==null) {
            entCertiOtherVo.setStatus(CommonConstants.CommonStatus.DISABLE);
        }
        Page<EntCertiOther> page=new Page<>(entCertiOtherVo.getPageNum(),entCertiOtherVo.getPageSize());
        QueryWrapper<EntCertiOther> entCertiOtherQueryWrapper = new QueryWrapper<>(entCertiOtherVo);
        if (entCertiOtherVo.getName()!=null){
            entCertiOtherQueryWrapper.like("name",entCertiOtherVo.getName());
        }
        if (entCertiOtherVo.getOrderBy()!=null) {
            if ("warningCount".equals(entCertiOtherVo.getOrderBy())) {
                entCertiOtherVo.setOrderBy("expireDate");
            }
            entCertiOtherQueryWrapper.orderBy(entCertiOtherVo.getOrderBy() != null, entCertiOtherVo.isAscFlag(), com.internetCafes.spms.common.utils.StringUtils.HumpToUnderline(entCertiOtherVo.getOrderBy()));
        }
        if (entCertiOtherVo.getWechatParam()!=null){
            entCertiOtherQueryWrapper.and(wrapper -> wrapper.like("name",entCertiOtherVo.getWechatParam()).or().like("code",entCertiOtherVo.getWechatParam()).or().like("release_organ",entCertiOtherVo.getWechatParam()));
        }
        entCertiOtherQueryWrapper.orderBy(true,false,"id");
        if (entCertiOtherVo.getValidityType()!=null) {
            switch (entCertiOtherVo.getValidityType()) {
                case -1:
                    entCertiOtherQueryWrapper.lt("expire_date", new Date());
                    break;
                case 0:
                    entCertiOtherQueryWrapper.gt("expire_date", new Date());
                    entCertiOtherQueryWrapper.lt("expire_date", entCertiOtherVo.getDays() != null && entCertiOtherVo.getDays() != "" ? DateUtils.getBeAfDay(Integer.parseInt(entCertiOtherVo.getDays())) : entCertiOtherVo.getMonths() != null && entCertiOtherVo.getMonths() != "" ? DateUtils.getBeAfMonth(Integer.parseInt(entCertiOtherVo.getMonths())) : null);
                    break;
                case 2:
                    entCertiOtherQueryWrapper.lt("expire_date", new Date());
                    entCertiOtherQueryWrapper.or(wrapper -> wrapper.gt("expire_date", new Date()).lt("expire_date", entCertiOtherVo.getDays() != null ? DateUtils.getBeAfDay(Integer.parseInt(entCertiOtherVo.getDays())) : entCertiOtherVo.getMonths() != null ? DateUtils.getBeAfMonth(Integer.parseInt(entCertiOtherVo.getMonths())) : null));
                    break;
            }
        }
        IPage<EntCertiOther> entCertiOtherIPage = entCertiOtherService.page(page,entCertiOtherQueryWrapper);
        List<EntCertiOther> records = entCertiOtherIPage.getRecords();
        for (int i = 0; i < records.size(); i++) {
            EntCertiOther entCertiOther = records.get(i);
            Map<String,Object>params = new HashMap<>();
            params.put("moduleCode", CommonConstants.RESOURCE_PIC_ENT_OTHER);
            params.put("moduleId", entCertiOther.getId());
            List<ResourceInfo> resourceInfoList = resourceInfoService.query(params);
            if (CollectionUtil.isNotEmpty(resourceInfoList)) {
                EntCertiOtherVo certiOtherVo = new EntCertiOtherVo();
                BeanUtils.copyProperties(entCertiOther, certiOtherVo);
                certiOtherVo.setCertiPic(resourceInfoList.get(0).getPath());
                records.set(i, certiOtherVo);
            }
        }
        return R.ok().put("data", entCertiOtherIPage);
    }

    @PostMapping("/list")
    @RequiresPermissions("certificate:certificateInfo:list")
    public R list(@RequestBody EntCertiOtherVo entCertiOtherVo) {
        entCertiOtherVo.setStatus(CommonConstants.CommonStatus.DISABLE);
        QueryWrapper<EntCertiOther> entCertiOtherQueryWrapper = new QueryWrapper<>(entCertiOtherVo);
        entCertiOtherQueryWrapper.orderBy(entCertiOtherVo.getOrderBy()!=null,entCertiOtherVo.isAscFlag(),entCertiOtherVo.getOrderBy());
        List<EntCertiOther> list = entCertiOtherService.list(entCertiOtherQueryWrapper);
        return R.ok().put("data", list);
    }

    @PostMapping("/export")
    @RequiresPermissions("certificate:certificateInfo:list")
    public void export(@RequestBody EntCertiOtherVo entCertiOtherVo, HttpServletResponse response) {
        entCertiOtherVo.setStatus(CommonConstants.CommonStatus.DISABLE);
        QueryWrapper<EntCertiOther> entCertiOtherWrapper = new QueryWrapper<>(entCertiOtherVo);
        entCertiOtherWrapper.orderBy(entCertiOtherVo.getOrderBy()!=null,entCertiOtherVo.isAscFlag(),entCertiOtherVo.getOrderBy());
        List<EntCertiOther> list = entCertiOtherService.list(entCertiOtherWrapper);
        try {
            if (list != null && list.size() > 0) {
                List<EntCertiOtherExcel> orderInfoExcelList = new ArrayList<>();
                EntCertiOtherExcel entCertiOtherExcel;
                for (EntCertiOther entCertiOther : list) {
                    entCertiOtherExcel = new EntCertiOtherExcel();
                    BeanUtils.copyProperties(entCertiOther, entCertiOtherExcel);
                    orderInfoExcelList.add(entCertiOtherExcel);
                }
                ExcelUtils.exportExcel(orderInfoExcelList, "其他证书信息统计", "其他证书信息统计", EntCertiOtherExcel.class, "其他证书信息统计.xls", response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/count")
    @RequiresPermissions("certificate:certificateInfo:list")
    public R count(@ModelAttribute EntCertiOther entCertiOther) {
        entCertiOther.setStatus(CommonConstants.CommonStatus.DISABLE);
        QueryWrapper<EntCertiOther> entCertiOtherQueryWrapper = new QueryWrapper<>(entCertiOther);
        int count = entCertiOtherService.count(entCertiOtherQueryWrapper);
        return R.ok().put("count", count);
    }

    @PostMapping("/AIRecognize")
    @RequiresPermissions("certificate:certificateInfo:list")
    public R AIRecognize(MultipartFile file) {
        if (file.isEmpty()) {
            return R.error("上传文件不能为空");
        }
        if (file.getSize() / 1024 > 1536) {
            return R.error("文件大小不能大于1.5M");
        }
        IdWorker id = new IdWorker(2);
        String fileName = id.nextId() + "";
        try {
            fileName = FileUtils.transform(file, picPath, fileName, 2, "M", new String[]{FileUtils.JPG, FileUtils.PNG});
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
        AIRecognizeInfo aiRecognizeInfo = qrCodeRecognizer.recognize(picPath + File.separator + fileName);
        try {
            if (aiRecognizeInfo == null || ObjectUtil.isAllFieldNull(aiRecognizeInfo)) {
                return R.error("上传图片有误或图片不清晰，请您确认后上传");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return R.ok().put("data",aiRecognizeInfo);
    }

    @GetMapping("/certiTypeCount")
    @RequiresPermissions("certificate:certificateInfo:list")
    public R countByCertiType() {
        QueryWrapper<EntCertiHonor> entCertiHonorQueryWrapper = new QueryWrapper<>();
        entCertiHonorQueryWrapper.eq("status",CommonConstants.CommonStatus.DISABLE);
        int honorCertiCount = entCertiHonorService.count(entCertiHonorQueryWrapper);
        QueryWrapper<EntCertiIso> entCertiIsoQueryWrapper = new QueryWrapper<>();
        entCertiIsoQueryWrapper.eq("status",CommonConstants.CommonStatus.DISABLE);
        int isoCertiCount = entCertiIsoService.count(entCertiIsoQueryWrapper);
        QueryWrapper<EntCertiOther> entCertiOtherQueryWrapper = new QueryWrapper<>();
        entCertiOtherQueryWrapper.eq("status",CommonConstants.CommonStatus.DISABLE);
        int otherCertiCount = entCertiOtherService.count(entCertiOtherQueryWrapper);
        QueryWrapper<EntCertiQuali> entCertiQualiQueryWrapper = new QueryWrapper<>();
        entCertiQualiQueryWrapper.eq("status",CommonConstants.CommonStatus.DISABLE);
        int qualiCertiCount = entCertiQualiService.count(entCertiQualiQueryWrapper);
        int total=honorCertiCount+isoCertiCount+otherCertiCount+qualiCertiCount;
        if (total==0){
            total++;
        }
        return R.ok().put("honorCertiCount",honorCertiCount)
                .put("honorCertiPercent",String.format("%.3f", (double)honorCertiCount/total))
                .put("isoCertiCount",isoCertiCount)
                .put("isoCertiPercent",String. format("%.3f", (double)isoCertiCount/total))
                .put("otherCertiCount",otherCertiCount)
                .put("otherCertiPercent",String.format("%.3f", (double)otherCertiCount/total))
                .put("qualiCertiCount",qualiCertiCount)
                .put("qualiCertiPercent",String.format("%.3f", (double)qualiCertiCount/total));
    }

    @GetMapping("/allTypeWarningGet")
    @RequiresPermissions("certificate:certificateInfo:list")
    public R getAllTypeWarning() {
        QueryWrapper<EntCertiHonor> entCertiHonorQueryWrapper = new QueryWrapper<>();
        entCertiHonorQueryWrapper.eq("status",CommonConstants.CommonStatus.DISABLE);
        entCertiHonorQueryWrapper.lt("expire_date", new Date());
        entCertiHonorQueryWrapper.or(wrapper -> wrapper.gt("expire_date", new Date()).lt("expire_date",DateUtils.getBeAfMonth(3)));
        int honorWarning = entCertiHonorService.count(entCertiHonorQueryWrapper);
        QueryWrapper<EntCertiIso> entCertiIsoQueryWrapper = new QueryWrapper<>();
        entCertiIsoQueryWrapper.eq("status",CommonConstants.CommonStatus.DISABLE);
        entCertiIsoQueryWrapper.lt("expire_date", new Date());
        entCertiIsoQueryWrapper.or(wrapper -> wrapper.gt("expire_date", new Date()).lt("expire_date",DateUtils.getBeAfMonth(3)));
        int isoWarning = entCertiIsoService.count(entCertiIsoQueryWrapper);
        QueryWrapper<EntCertiOther> entCertiOtherQueryWrapper = new QueryWrapper<>();
        entCertiOtherQueryWrapper.eq("status",CommonConstants.CommonStatus.DISABLE);
        entCertiOtherQueryWrapper.lt("expire_date", new Date());
        entCertiOtherQueryWrapper.or(wrapper -> wrapper.gt("expire_date", new Date()).lt("expire_date",DateUtils.getBeAfMonth(3)));
        int otherWarning = entCertiOtherService.count(entCertiOtherQueryWrapper);
        QueryWrapper<EntCertiQuali> entCertiQualiQueryWrapper = new QueryWrapper<>();
        entCertiQualiQueryWrapper.eq("status",CommonConstants.CommonStatus.DISABLE);
        entCertiQualiQueryWrapper.lt("expire_date", new Date());
        entCertiQualiQueryWrapper.or(wrapper -> wrapper.gt("expire_date", new Date()).lt("expire_date",DateUtils.getBeAfMonth(3)));
        int qualiWarning = entCertiQualiService.count(entCertiQualiQueryWrapper);
        return R.ok().put("honorWarning",honorWarning)
                .put("isoWarning",isoWarning)
                .put("otherWarning",otherWarning)
                .put("qualiWarning",qualiWarning);
    }
}
